﻿using System;
using System.ComponentModel;
using System.Windows.Forms;
using Streambolics.Gui;

namespace Streambolics.Hp41s.Gui
{
    /// <summary>
    ///     A control linked to an execution engine.
    /// </summary>

    public class EngineControl : StandardControl
    {
        private Engine _Machine;

        /// <summary>
        ///     Creates the control
        /// </summary>

        public EngineControl ()
        {
            AllowDrop = true;
        }

        protected virtual void OnDisplayChanged (EventArgs e)
        {
        }

        void _Machine_DisplayChanged (object sender, EventArgs e)
        {
            OnDisplayChanged (e);
        }

        protected virtual void Link (Engine aEngine)
        {
            aEngine.DisplayChanged += new EventHandler (_Machine_DisplayChanged);
            _Machine_DisplayChanged (this, EventArgs.Empty);
        }

        protected virtual void Unlink (Engine aEngine)
        {
            aEngine.DisplayChanged -= new EventHandler (_Machine_DisplayChanged);
        }

        /// <summary>
        ///     The machine to which the control is linked.
        /// </summary>

        [Browsable (false)]
        public Engine Machine
        {
            get
            {
                return _Machine;
            }
            set
            {
                if (value != _Machine)
                {
                    if (_Machine != null)
                        Unlink (_Machine);
                    _Machine = value;
                    if (_Machine != null)
                        Link (_Machine);
                }
            }
        }

        protected override void Dispose (bool disposing)
        {
            base.Dispose (disposing);
            Machine = null;
        }

        protected T GetDragData<T> (DragEventArgs aDragData) where T : Data
        {
            return DragData.GetDragData<T> (aDragData, this);
        }

        protected Instruction GetInstruction (DragEventArgs aDragDrop)
        {
            if (_Machine == null)
            {
                return null;
            }
            Data d = DragData.GetDragData<Data> (aDragDrop, this);
            if (d == null)
            {
                return null;
            }
            return d.ToInstruction ();
        }


    }
}
